#函数的进阶
#参数的补充
#参数内存地址相关，函数执行传参时，传递的是内存地址;
# 好处：节省内存、对于可变类型且函数中修改元素的内容，所有的地方都会修改。
# def func(data):
#     print("data:"+str(id(data)))
#     data[1]=77
# v1=[11,22,33]
# print(' v1 :'+str(id(v1)))
# func(v1)
# print(v1)
#拷贝传参，只进行值拷贝
# import copy
# def func(new):
#     print(id(new))
# data=[11,22,33]
# new=copy.deepcopy(data)
# print(id(data))
# print(new)
# func(new)
# print(id(new))


#函数的返回值是内存地址，引用计数器+1
# def func():
#     data=[11,22]
#     print(id(data))
#     return data
# v1=func()
# print(id(v1))
# v2=func()
# print(id(v2))

# def func():
#     data="skxsk"  #缓存和驻留机制——字符串和数字
#     print(id(data))
#     return data
# v1=func()
# print(id(v1))
# v2=func()
# print(id(v2))

#参数的默认值
#在特定情况下，默认参数的值是可变类型list/dict/set  & 函数内部会修改这个值 下，参数的默认值有坑
#坑1：
# def func(a1,a2=[1,4]):
#     a2.append(88)
#     print(a1,a2)
# func(100)
#在函数内存中会维护一块区域存储
# func(200)

#坑2： 在函数内存中会维护一块区域存储
# def func(a1,a2=[1,3]):
#     a2.append(a1)
#     return a2
# v1=func(10)
# print(v1)
# v2=func(20)
# print(v2)
# v3=func(30,[11,44])
# print(v3)

#坑3：
# def func(a1,a2=[1,3]):
#     a2.append(a1)
#     return a2
# v1=func(10)
# v2=func(20)
# v3=func(30,[11,44])
# print(v1)
# print(v2)
# print(v3)


#动态参数
# def func1(*args,**kwargs):
#     print(args,kwargs)
#形参固定，实参用*和**
# def func2(a1,a2):
#     print(a1,a2)
# func2(*[1,4])#打散
# func2(**{"a1":11,"a2":22})

#形参和实参都用*和**
# def func(*args,**kwargs):
#     print(args,kwargs)
# func(11,22)
# func(11,22,name='xiaofeng',age=8)
# func(*[1,4],**{"k1":1,"k2":2}) #循坏拷贝，放到形参中




